package com.game.battle.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


/**
 * 不同概率抽奖工具包
 *
 * @author Shunli
 */

public class ProbabilityGift {
    private int index;
    private String giftId;
    private String giftCnt;
    private double probability;

    public ProbabilityGift(int index, String giftId, String giftCnt, double probability) {
        this.index = index;
        this.giftId = giftId;
        this.giftCnt = giftCnt;
        this.probability = probability;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public String getGiftId() {
        return giftId;
    }

    public void setGiftId(String giftId) {
        this.giftId = giftId;
    }

    public String getGiftCnt() {
        return giftCnt;
    }

    public void setGiftCnt(String giftCnt) {
        this.giftCnt = giftCnt;
    }
    
    public double getProbability() {
        return probability;
    }

    public void setProbability(double probability) {
        this.probability = probability;
    }

    @Override
    public String toString() {
        return "ProbabilityGift:[index=" + index + ", giftId=" + giftId + ", giftCnt=" + giftCnt + ", probability=" + probability + "]";
    }
    
	/**
	 * 抽奖
	 *
	 * @param orignalRates  原始的概率列表，保证顺序和实际物品对应
	 * @return 物品的索引
	 */
	public static int getGiftIndex(List<Double> orignalRates) {
		if (orignalRates == null || orignalRates.isEmpty()) {
			return -1;
		}

		int size = orignalRates.size();

		// 计算总概率，这样可以保证不一定总概率是1
		double sumRate = 0d;
		for (double rate : orignalRates) {
			sumRate += rate;
		}

		// 计算每个物品在总概率的基础下的概率情况
		List<Double> sortOrignalRates = new ArrayList<Double>(size);
		Double tempSumRate = 0d;
		for (double rate : orignalRates) {
			tempSumRate += rate;
			sortOrignalRates.add(tempSumRate / sumRate);
		}

		// 根据区块值来获取抽取到的物品索引
		double nextDouble = Math.random();
		sortOrignalRates.add(nextDouble);
		Collections.sort(sortOrignalRates);

		return sortOrignalRates.indexOf(nextDouble);
	}

	public static ProbabilityGift getProbabilityGift(List<ProbabilityGift> gifts) {
		List<Double> orignalRates = new ArrayList<Double>(gifts.size());
		for (ProbabilityGift gift : gifts) {
			double probability = gift.getProbability();
			if (probability < 0) {
				probability = 0;
			}
			orignalRates.add(probability);
		}
		 try {
			 int orignalIndex = ProbabilityGift.getGiftIndex(orignalRates);
			 ProbabilityGift retGift = gifts.get(orignalIndex);
			 System.out.println(retGift);
			 return retGift;
		 } catch (Exception e) {
			 System.out.println("lottery failed, please check it!");
		 }
		 return null;
	}

	public static void getProbabilityGiftTest(List<ProbabilityGift> gifts) {
		List<Double> orignalRates = new ArrayList<Double>(gifts.size());
		for (ProbabilityGift gift : gifts) {
			double probability = gift.getProbability();
			if (probability < 0) {
				probability = 0;
			}
			orignalRates.add(probability);
		}
		// statistics
		Map<Integer, Integer> count = new HashMap<Integer, Integer>();
		double num = 1000000;
		for (int i = 0; i < num; i++) {
			int orignalIndex = ProbabilityGift.getGiftIndex(orignalRates);

			Integer value = count.get(orignalIndex);
			count.put(orignalIndex, value == null ? 1 : value + 1);
		}

		for (Entry<Integer, Integer> entry : count.entrySet()) {
			System.out.println(gifts.get(entry.getKey()) + ", count=" + entry.getValue() + ", probability="
					+ entry.getValue() / num);
		}
	}
}
